<?php
/**
 * Обьект параметров для jqGrid.
 * Содержит главные параметры для grid, его функциональности, формирования.
 * @author nrnwest@gmail.com
 *
 */
class Arm_Grid_JqGrid_Params
{
        
    /**
     * Индефикатор grid
     * @var string
     */
    private $_idGrid = null;
    
    /**
     * id page
     * @var string
     */
    private $_idPagerGrid = null;
    
    /**
     * Параметры настройки grid
     * @var array
     */
    private $_params = array('datatype' => "'json'",
                             'mtype'    => "'POST'",
                             'rowNum'   => 5,
                             'rowList'  => '[5,10,20,30,50,100]',
                             'viewrecords' => 'true',
                             'sortable'    => 'true',
                             'rownumbers'  => 'true',
                             'scroll'     =>  '1',
                             'viewsortcols' => '[true, \'vertical\', true]' // horizontal
                             );

    /**
     * Параметры для блока pager управления записями.
     * @var array
     */
    private $_paramsPager = array('view'=>'true',
                                  'del'=>'true',
                                  'add'=>'true',
                                  'edit'=>'true'
                                  );

    /**
     * Параметры для измения рамеров grid
     * @var array
     */
    private $_resize = array('minWidth'=>350,'maxWidth'=>1200,'minHeight'=>120, 'maxHeight'=>600);
    
    /**
     * Включить линейное редактирования.
     * @var bool
     */
    private  $_inline = false;
    
    /**
     * Упраления данными в grid по умолчанию включено.
     * @var strint
     */
    private $_direct = true;
    
    /**
     * Arm_Grid_JqGrid
     * 
     * @var Arm_Grid_JqGrid
     */
    private $_grid  = null;
    
    /**
     * Конструктор
     * @param string $idGrid id grid
     * @param string $url урл получения данных.
     */
    public function __construct($idGrid=null, $url=null, Zend_Config $config = null, Arm_Grid_JqGrid $grid)
    {
       $this->_grid = $grid;     
       if($idGrid === null and $config === null) {
            throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Вы должны указать или $idGrid, или задать масив конфига $config'));
        }
        if($idGrid === null) {
            $idGrid = $config->idGrid;
        }
        if($idGrid === null) {
            throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Вы должны установить ключ в конфиге grid.idGrid="name"'));
        }
        $this->setIdGrid($idGrid);
        $this->setIdPager();
        if($url === null and $config !== null) {
            $url = $config->url;
        }
        $this->setUrl($url);
        $this->setEditUrl($url);
        // установка кофигурационых данных
        if($config  !== null) {
           $this->_setConfig($config, $grid);
        }
    }
    
    /**
     * Установка конфига
     */
    protected function _setConfig(Zend_Config $conig = null, Arm_Grid_JqGrid $grid = null)
    {
        $conig = $conig->toArray();
        if(array_key_exists('model', $conig) === false) {
            throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Модель не установлена в конфигурационом файле, секция model'));
        }
        $model = $conig['model'];
        unset($conig['model']);
        if(array_key_exists('cols', $conig) === false) {
           throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Не установлены столбцы, секция cols')); 
        }
        $cols  = $conig['cols'];
        unset($conig['cols']);
        foreach ($conig as $k=>$v) {
        	$m = 'set'. $k;
        	if(method_exists($this, $m)) {
        	    $this->{$m}($v);
        	    continue;
        	}
            if(method_exists($grid, $m)) {
                $grid->{$m}($v);
                continue;
            }
            throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Не правильный параметер в когфиге  "%s"', $k));
        }
       // Установка модели
       if(array_key_exists('name', $model) === false) {
           throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Не установлено имя модели'));
       }
       $modelObject = new $model['name'];
       if($modelObject instanceof Zend_Db_Table) {
            // устновка модели Zend_Db_Table
            $grid->setModel($modelObject, $grid->getIdCol());    
       } else {
           if(array_key_exists('methods', $model) === false) {
               throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Не установлена секция methods'));
           } 
           $grid->setModel($modelObject, $grid->getIdCol(), $model['methods']['select']);
           if(array_key_exists('insert', $model['methods']) === false or 
              array_key_exists('delete', $model['methods']) === false or 
              array_key_exists('update', $model['methods']) === false ) {
                  throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('В секции methods должны быть установленны секции insert
                  delete update'));
              }
           $grid->setManipulationMethods($model['methods']['update'], $model['methods']['delete'], $model['methods']['insert']);    
       }
       // Установка столбцов
       foreach ($cols as $k => $v) {
           $message = Arm_Translate::_('Не устновлен ключ в столбце "%s" ключ', $k);
           $this->_checkKey('name', $v, $message);
           $this->_checkKey('label', $v,  $message);
           $name  = $v['name'];
           $label = $v['label'];
           unset($v['name']);
           unset($v['label']);
           $grid->addColumn($name, Arm_Translate::_($label), $v);
       }
          
     }
     
     /**
      * Возвращения параметров grid в виде строки, для вставки в шаблон вида.
      * Данный метод сработает правильно тогда когда все стобци будут установленны в grid
      * 
      * @return string
      */
     public function getStrsParams()
     {
        $result = array();
        $colNames = $this->_grid->getColumnsLabelStr();
        if($colNames !== false) {
           $this->_params['colNames'] = '['  .  $colNames . ']';
        }
        $colModel = $this->_grid->getColumnsModelStr();
        if($colModel !== false)  {
           $this->_params['colModel'] = '['  . "\n" . $colModel .  "\n" .  ']';
        }
        $this->_params['pager']  = 'jQuery(\'#' . $this->getIdPagerPanel() . '\')';
        //  установка базового сортировщика по колонке, устанавливаем тогд когда его еще не установили
        if(array_key_exists('sortname', $this->_params) === false) {
            $this->setSortname($this->_grid->getIdCol());
        }
        if(array_key_exists('sortorder', $this->_params) === false) {
            $this->setSortorder('desc');
        }
        foreach ($this->_params as $k=>$v){
            $result[] =  $k  . ':' . $v;
        }
        return implode(",\n", $result) . "\n";
     }
     
     /**
      * Вернет названия столбца который содержит id данные.
      * 
      * @return string
      */
     public function getIdCol()
     {
        return $this->_grid->getIdCol();
     }
    
    /**
     * Проверка существоания ключа, если его нет будет брошено исключение.
     * @param string $key
     * @param array $array
     * @param string $message
     */
    protected function _checkKey($key, $array, $message) 
    {
        if(array_key_exists($key, $array)=== false){
            throw new Arm_Grid_JqGrid_Exception($message . ':' . $key);
        }    
    }
    
    
    /**
     * Вернет параметры для главных настроек grid
     * 
     * @return array
     */
    public function getGridParams()
    {
       return  $this->_params;
    }
    
    /**
     * Вернет параметры для панели страниц.
     * 
     * @return array
     */
    public function getPagerPanelParams()
    {
        return $this->_paramsPager;
    }
    
    /**
     * Вернет id grid
     * 
     * @return string
     */
    public function getIdGrid()
    {
        return $this->_idGrid;
    }
    
    /**
     * Вернет id для панели страниц grid
     * 
     * @return string
     */
    public function getIdPagerPanel()
    {
        return $this->_idPagerGrid;
    }
    
    /**
     * Установка параметра для формирования grid
     * @param string $param
     * @param string $value
     * @return Arm_Grid_JqGrid_Params
     */
    protected function _setParam($param, $value)
    {
        $this->_params[$param] = $value;
        return $this;
    }
    
    
    /**
     * Установка редактирования inline
     * 
     * @return Arm_Grid_JqGrid_Params
     */
    public function setInline($set=true)
    {
        $set = (bool) $set;
        $this->_inline  =  $set;
        return $this;        
    }
    
    /**
     * Включить inline редактирования или нет
     * 
     * @return  bool
     */
    public function isInline()
    {
        if($this->_inline === false or $this->_direct  === false) {
            return false;
        }
        return true;
    }
    
    /**
     * Включить | Выключить управления данными в grid
     * 
     * @return Arm_Grid_JqGrid_Params
     */
    public function setDirect($set = false)
    {
        $set = (bool) $set;
        $this->_direct = $set;
        if($this->_direct  === false) {
            // удалим с панели управления все лишние
            // кроме view
            foreach ($this->_paramsPager as $k=>$v){
                if($k === 'view') {
                    $this->_paramsPager['view'] = 'true';
                } else {
                    $this->_paramsPager[$k] = 'false';
                }    
            }
            
        }
        return $this;
    }
    
  
    
    /**
     * Включить управления данными в grid
     * 
     * @return bool
     */
    public function isDirect()
    {
        return $this->_direct;
    }
    
    /**
     * Разрешения сортировки столбцов в веб интерфейсе 
     * 
     * @param bool $set
     * @return Arm_Grid_JqGrid_Params
     */
    public function setSortable($set = true)
    {
       $set = (bool) $set;
       if($set) {
           $this->_setParam('sortable', 'true');
       } else {
           $this->_setParam('sortable', 'false');
       }
       return  $this;
    }
    
    /**
     * Установка первым столбцом порядковый номер ряда.
     * 
     * @param bool $set
     * @return Arm_Grid_JqGrid_Params
     */
    public function setRownumbers($set = true)
    {
       $set = (bool) $set;
       if($set) {
           $this->_setParam('rownumbers', 'true');
       } else {
           $this->_setParam('rownumbers', 'false');
       }
       return  $this;
    }
    
    /**
     * Установка скролинга записей,выбор количества записей на странице 
     * автоматически отключается.
     * 
     * @param bool $set
     * @return Arm_Grid_JqGrid_Params
     */
    public function setScroll($set = 1)
    {
       $set = (int) $set;
       $this->_setParam('scroll', $set);
       return  $this;
    }
    
    
    /**
     * Установка idGrid, также он автоматически установаляет 
     * свойство grid pager - добавив к idGrid символ p
     * @param string $idGrid
     * @return Arm_Grid_JqGrid_Params
     */
    public function setIdGrid($idGrid)
    {
       $this->_idGrid = $idGrid;
       return  $this;
    }
    
    /**
     * Установка id pager
     * 
     * @return Arm_Grid_JqGrid_Params
     */
    public function setIdPager()
    {
        $this->_idPagerGrid = 'p' . $this->_idGrid;
        return $this;
    }
    
    /**
     * Установка оглавления для таблицы грида.
     * @param string $title
     *  @return Arm_Grid_JqGrid_Params
     */
    public function setCaption($title)
    {
        return $this->_setParam('caption', "'" . $title . "'");
    }
    
    /**
     * Сколько строк показывать в таблице за один раз.
     * @param int $num
     * @return Arm_Grid_JqGrid_Params
     */
    public function setRowNum($num=5)
    {
       return $this->_setParam('rowNum', $num);
    }
    
    /**
     * Устанавливает параметер который даст возможность пользователю
     * выбирать количество показываемых строк в таблице.
     * @param array $array
     * @return Arm_Grid_JqGrid_Params
     */
    public function setRowList($array=array(5, 10, 20, 30, 50, 100))
    {
      return $this->_setParam('rowList', $array);
    }
    
    /**
     * поле, которое по-умолчанию используется для сортировки
     * 
     * @param string $col колонка по которой сортируем.
     * @return Arm_Grid_JqGrid_Params
     */
    public function setSortname($col)
    {
      return $this->_setParam('sortname', "'" . $col . "'");
    }
    
    /**
     * Порядок сортировки
     * 
     * @param string $type по умолчанию asc возврастания, если задать false установится по убыванию.
     * @return Arm_Grid_JqGrid_Params
     */
    public function setSortorder($type='asc')
    {
        if($type !== 'asc') {
            $type = 'desc';
        }
       return $this->_setParam('sortorder', "'". $type."'");
    }
    
    /**
     * указывает, нужно ли показывать в панели управления общее количество записей
     * 
     * @param bool $view
     * @return Arm_Grid_JqGrid_Params
     */
    public function setViewrecords($view = true)
    {
        if($view) {
            $view = 'true';
        } else {
            $view = 'false';
        }
       return $this->_setParam('viewrecords', $view);    
    }
    
    /**
     * Ширина таблицы grid
     * @param int $width
     */
    public function setWidth($width)
    {
        return $this->_setParam('width', $width);
    }
    
    /**
     * Усновка размеров grid, для функциональности, изменения размеров
     * @param array $options
     * @return Arm_Grid_JqGrid_Params
     */
    public function setResize($options)
    {
        $keys    = array('minwidth'=>'minWidth', 'maxwidth'=>'maxWidth', 'minheight'=>'minHeight', 'maxheight'=>'maxHeight');
        foreach ($options as $k=>$v){
            $k=strtolower($k);
            if(array_key_exists($k, $keys) === false)  {
               throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Не допустимый ключ "%s"', $k));
            }
            $k = $keys[$k];
            $options[$k] = $v;
            unset($this->_resize[$k]);
        }
        $options = array_merge($options, $this->_resize);
        $this->_resize = $options;
        return $this;
    }
    
    /**
     * Параметры для изменения размеров,
     * Вовзращает сформированную строку, для вставки в html шаблон.
     * 
     * @return string
     */
    public function getResize()
    {
        $res = array();
        foreach ($this->_resize  as $k=>$v) {
            $res[]=$k . ':' . $v;
        }
        return implode(', ', $res);
    }
    
    /**
     * Установка урла для редактирования данных.
     * 
     * @param string|null|false $url если null система установит урл на базе параметра базового url.W
     * @return Arm_Grid_JqGrid_Params
     */
    public function setEditUrl($url=null)
    {
        if($url === null) {
            $request = Arm_Core::getRequest();
            if($request === null) {
                throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Не задан базовый url для отображения grid'));
            }
            $url = $request->getRequestUri();    
        }
        
       return $this->_setParam('editurl', "'" . $url . "'");
    }

    
      
    
    /**
     * Установка иконок сортировки  на столбцах.
     * @param $params
     */
    public function setViewsortcols($params=array())
    {
        // 'viewsortcols' => '[true, \'vertical\', true]' // horizontal
        $params = (array) $params;
        $view  = true;
        $type  = 'vertical';
        $sort  = true;
        if(isset($params['view'])){
            $view = (bool)$view;
        }
        if(isset($params['type'])){
            $type = $type;
        }
        if(isset($params['sort'])){
            $sort = (bool)$sort;
        }
        $type = $type === 'vertical' ?  'vertical' : 'horizontal';
        $view = $view === true ? 'true' : 'false';
        $sort = $sort === true ? 'true' : 'false';
        return $this->_setParam('viewsortcols', "[$view, '$type', $sort]");
    }
    
    /**
     * Расширяет таблицу на максимальный допустимы размер.
     */
    public function setAutowidth()
    {
        return $this->_setParam('autowidth', 'true');
    }
    
    
    
    /**
     * Установка url grid при запросе к данному url
     * должен возвращаться масив данных в виде json
     * Если url не установлен система установит его автоматически
     * по текущему модулю, контролеру, действию.
     * @param string|null $url
     * @return Arm_Grid_JqGrid_Params
     */
    public function setUrl($url=null)
    {
        if($url === null) {
            $request = Arm_Core::getRequest();
            if($request === null) {
                throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Система не смогла установить url для получения данных, задайте его в конструкторе'));
            }
            $url = $request->getRequestUri();    
        }
          
        return $this->_setParam('url', "'" . $url . "'");
    }
    
    /**
     * Вовзвращает значения ключа.
     * @param string $name
     */
    public function getParam($name)
    {
        if(array_key_exists($name, $this->_params) === false) {
            return null;
        }
        return trim($this->_params[$name],"'");
    }
    
    /**
     * Установка параметров для блока pager
     * @param  array $params параметры которые включит, выключить true|false, по умолчанию все включенно.
     * @return Arm_Grid_JqGrid_Params
     */
    public function setPager($params=array('edit'=>true, 'del'=>true, 'add'=>true, 'view'=>true))
    {
        foreach ($params as $k=>$v) {
          if(array_key_exists($k, $this->_paramsPager) === false) {
              throw new Arm_Grid_JqGrid_Exception(Arm_Translate::_('Не правильное значение для ключа, возможные edit|del|add|view'));
           }
           $v = true === (bool) $v ? 'true':'false';
           $this->_paramsPager[$k] = $v;
        }
        return $this; 
    }
}